import {config} from '@/utils/config'
import store from "../store"

let lastTime = 0;

// 节流函数，确保弹窗或提示只能在一定时间内触发一次
const throttle = (fn, interval = 300) => {
    return function (...args) {
        const now = new Date().getTime();
        if (now - lastTime >= interval) {
            lastTime = now;
            fn(...args);
        }
    };
};

const request = (url, data, type = "get", isShowLoad = true, isErrBack = false, header = {}) => {
    let apiUrl = config.baseURL + url;
    let headObj = {};

    // 获取token
    const token = store.state.auth.token || uni.getStorageSync('token') || '';
    if (token) headObj['token'] = token;
    if (token) headObj['X-Access-Token'] = token;

    // 合并自定义头部信息
    headObj = {...headObj, ...header};

    return new Promise((resolve, reject) => {
        if (isShowLoad) {
            uni.showLoading({
                mask: true,
                title: '数据加载中',
            });
        }
        uni.request({
            url: apiUrl,
            method: type,
            data: data || {},
            header: headObj,
            timeout: config.loadingTime,
            success(response) {
                const res = response;
                // 状态码处理
                if (res.statusCode === 200) {
                    if (res.data?.code === 0) {
                        resolve(res.data);
                    } else {
                        handleError2(res);
                    }
                } else {
                    handleError(res);
                }
            },
            fail(err) {
                console.log(err);
                if (err.errMsg.indexOf('request:fail') !== -1) {
                    showToast('网络异常', 'error');
                } else {
                    showToast('未知异常');
                }
                reject(err);
            },
            complete() {
                // 隐藏加载和提示
                uni.hideLoading();
                uni.hideToast();
            }
        });
    });

    // 错误处理
    function handleError(res) {
        switch (res.statusCode) {
            case 400:
                showModal("提示", res.data.msg);
                break;
            case 401:
                uni.clearStorageSync();
                showModal("提示", "请登录", () => {
                    setTimeout(() => {
                        uni.reLaunch({url: '/pages/auth/index'});
                    }, 1000);
                });
                break;
            case 404:
                showToast('请求地址不存在...');
                break;
            case 500:
                showToast('服务器异常，请稍后重试');
                break;
            default:
                uni.clearStorageSync();
                showToast('请重试...');
                break;
        }
    }

    // 错误处理
    function handleError2(res) {
        switch (res.data.code) {
            case 1:
                showModal("提示", res.data.msg, () => {
                    if (isErrBack) {
                        setTimeout(() => {
                            uni.navigateBack({delta: 1});
                        }, 200);
                    }
                });
                break;
            case 400:
                showModal("提示", res.data.msg);
                break;
            case 401:
                uni.clearStorageSync();
                showModal("提示", "请登录", () => {
                    setTimeout(() => {
                        uni.reLaunch({url: "/pages/auth/index"});
                    }, 1000);
                });
                break;
            case 404:
                showToast('请求地址不存在...');
                break;
            case 500:
                showModal("提示", res.data.msg);
                break;
            default:
                uni.clearStorageSync();
                showToast('请重试...');
                break;
        }
    }

    // 显示 Toast
    function showToast(title, icon = "none") {
        uni.showToast({
            title,
            icon,
            duration: 2000,
        });
    }

    // 显示 Modal
    function showModal(title, content, callback = () => {
    }) {
        // 使用节流来避免频繁弹窗
        throttle(() => {
            uni.showModal({
                title,
                content,
                showCancel: false,
                success: callback,
            });
        })();
    }
};

export default request;